using System;
using Microsoft.DirectX.DirectInput;
using SharpWars.Core.Helpers;
using System.Collections.Generic;

namespace SharpWars.Core.Input
{
	public sealed class Keyboard : IDisposable
	{
		private Device device = null;

		private bool[] keysPressed = null;

		private bool[] keysTriggered = null;

		private bool isLost = false;

		public Keyboard()
		{
			this.keysPressed = new bool[ 256 ];
			this.keysTriggered = new bool[ 256 ];
		}

		internal void Initialize( GameWindow gameWindow )
		{
			this.device = new Device( SystemGuid.Keyboard );
			this.device.SetDataFormat( DeviceDataFormat.Keyboard );
			this.device.SetCooperativeLevel( gameWindow, CooperativeLevelFlags.Background |
											 CooperativeLevelFlags.NonExclusive );

			try
			{
				this.device.Acquire();
			}
			catch( InputLostException )
			{
				this.isLost = true;
			}
		}

		public void Update()
		{
			if( this.device == null )
			{
				return;
			}

			try
			{
				if( this.isLost )
				{
					this.device.Acquire();
				}
				else
				{
					Key[] pressed = this.device.GetPressedKeys();

					UpdateTriggeredKeys( pressed );
					UpdatePressedKeys( pressed );

					if( IsKeyPressed( Key.W ) == true )
					{

					}
				}
			}
			catch( InputLostException )
			{
				this.isLost = true;
			}
		}

		private void UpdateTriggeredKeys( Key[] pressed )
		{
			for( int i = 0; i < this.keysTriggered.Length; i++ )
			{
				this.keysTriggered[ i ] = false;
			}

			for( int i = 0; i < pressed.Length; i++ )
			{
				int key = ( int )pressed[ i ];

				if( !this.keysPressed[ key ] )
				{
					this.keysTriggered[ key ] = true;
				}
			}
		}

		private void UpdatePressedKeys( Key[] pressed )
		{
			for( int i = 0; i < this.keysPressed.Length; i++ )
			{
				this.keysPressed[ i ] = false;
			}

			for( int i = 0; i < pressed.Length; i++ )
			{
				int key = ( int )pressed[ i ];
				this.keysPressed[ key ] = true;
			}
		}

		public bool IsKeyPressed( Key key )
		{
			return this.keysPressed[ ( int )key ];
		}

		public bool IsKeyTriggered( Key key )
		{
			return this.keysTriggered[ ( int )key ];
		}

		#region IDisposable Members

		public void Dispose()
		{
			if( this.device != null )
			{
				this.device.Unacquire();
				DisposeHelper.Dispose( this.device );
			}
		}

		#endregion
	}
}
